/**
 * @mainpage Forza4
 *
 * Programma che implementa il famoso gioco da tavolo Forza4,
 * in cui per vincere è necessario disporre 4 gettoni in fila
 * del proprio colore (in qualsiasi direzione compreso in obliquo).
 * 
 * @author Giulio Malavasi
 */

/**
 * @file 
 * File contenente l'intero programma.
 */
#include <iostream>
#include <gtk/gtk.h>
#include "variables_data.h"
#include "controls.h"
#include "windows_settings.h"
#include "ingame_operations.h"
using namespace std;

#ifdef DEBUG_MODE
unsigned int MASK = 1;
#endif

GtkBuilder *builder;

/**
 * La variabile 'gamer' di tipo enumerato serve per stabilire a chi appartiene una cella
 * cioè se è stato inserito un gettone rosso o giallo e verrà usata nei controlli
 * per verificare la vincita del primo o del secondo giocatore. Inoltre viene utilizzata per 
 * stabilire di volta in volta a chi spetta l'attuale turno.
 * La matrice conterrà proprio il valore player1 o player2 a seconda di quale giocatore 
 * ha inserito il suo gettone.
 * I controlli di vincita si basano sullo scandire gli indici di questa matrice.
 */
giocatori gamer=player1, campo_gioco[6][7];

/**
 * Variabile booleana che servirà per settare la sensitive delle
 * celle a true o false a seconda del suo valore (all'interno della funzione ::set_all_sensitive).
 */
bool flag=false;

/**
 * Questa matrice conterrà i numeri relativi alle posizioni dei bottoni da 1 a 42.
 */
unsigned int campo_gioco_pos[6][7];

/**
 * Viene usato nei controlli di vincita, per tenere il conto di quanti
 * sono i gettoni rossi in sequenza.
 */
unsigned int red_cell=0;

/**
 * Viene usato nei controlli di vincita, per tenere il conto di quanti
 * sono i gettoni gialli in sequenza.
 */
unsigned int yellow_cell=0;

/**
 * Viene usata per tenere il conto di quanti gettoni totali sono stati inseriti.
 * Se si riempie il campo di gioco allora viene decretato il pareggio.
 */
unsigned int token=0;

/**
 * Viene usata per contare il totale delle partite vinte del giocatore rosso.
 */
unsigned int r_m_won=0;

/**
 * Viene usata per contare il totale delle partite vinte del giocatore giallo.
 */
unsigned int y_m_won=0; 

/**
 * Puntatore alla stringa costante str1. 
 * Visto che è globale verrà usato per puntare anche alla stringa che si creerà
 * quando viene impostato il nome del giocatore 1 dal menù modifica.
 */
const char *P1=str1;

/**
 * Puntatore alla stringa costante str1. 
 * Visto che è globale verrà usato per puntare anche alla stringa che si creerà
 * quando viene impostato il nome del giocatore 2 dal menù modifica.
 */
const char *P2=str2;

/**
 * Funzione di gestione 'click' delle pedine.
 * Il puntatore costante "nome" punta alla label "image01"; nel 1° e 2°
 * posto dell'array 'num' finiscono i caratteri corrispondenti alle due
 * cifre del numero della suddetta label e in aggiunta viene messo il terminatore;
 * poi viene dichiarato un puntatore costante ad array di carattere che servirà
 * nella funzione di seguito per rendere 'non cliccabile' il bottone (cioè la cella)
 * appena premuto (poichè il posto per questa pedina non può più essere usato).
 * Infatti appena si clicca la cella, questa viene colorata secondo il colore 
 * del giocatore che ha posizionato la sua pedina. In seguito si rende cliccabile
 * la casella sopra quella appena inserita (come da regolameto).
 * Dopodichè viene chiamata la funzione principale per i controlli ::check_winner.
 * Se non c'è un vincitore ma si sono esaurite le celle di tutto il campo
 * allora viene mostrata la finestra di pareggio. 
 * Se questi eventi non si verificano viene semplicemente passato il turno
 * con la funzione ::change_turn.
 */
extern "C" void button_clicked_event(GtkWidget *widget, gpointer user_data)
{
	const char* nome=gtk_label_get_text(GTK_LABEL(user_data));
	char num[3];
	num[0]=nome[5];
	num[1]=nome[6];
	num[2]='\0';

	const char *numero=num;
	unsigned int id_bottone=((num[0]-'0')*10+(num[1]-'0')); //ricavo il numero dai caratteri 
	unsigned int id2_bottone;

	if(gamer==player1){	
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder,nome)), "red_token.png");	
		set_cell_owner(id_bottone);
					  }	

	else{
		gtk_image_set_from_file(GTK_IMAGE(gtk_builder_get_object(builder,nome)), "yellow_token.png");			
		set_cell_owner(id_bottone);
		}
	
	gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,numero)), false);

	//rende sensitive la cella sopra quella appena usata
	if(id_bottone>7){			
		id2_bottone=id_bottone-7;	
		num[0]=static_cast<char>(id2_bottone/10+48);
		num[1]=static_cast<char>(id2_bottone%10+48);
		gtk_widget_set_sensitive(GTK_WIDGET(gtk_builder_get_object(builder,numero)), true);
					}

	token++;	
	
	check_winner();	

	if(token==42){
		GtkWidget *draw_dialog =GTK_WIDGET(gtk_builder_get_object(builder,"dialog2"));
		gtk_widget_show_all(draw_dialog); 			 
			     }

	change_turn();
}	

/**
 * Nel main vengono inizializzati i vari oggetti per la libreria gtk,
 * viene caricata l'interfaccia grafica creta con il programma Glade
 * e vengono collegati tutti i segnali relativi agli eventi futuri
 * con l'interfaccia grafica. Dopo viene chiamata la funzione 
 * ::inizializza_campo che prepara appunto il campo per la partita e si setta
 * la label del giocatore rosso che apparirà nella barra inferiore del campo 
 * (poichè di default comincia il giocatore red, poi si alternerà con la label
 * relativa al giocatore giallo).
 * Infine viene chiamata la funzione gtk_main che genera un 'ciclo infinito'
 * in cui il programma aspetta che vengano generati gli eventi dall'utente
 * (nel nostro caso per esempio il click delle pedine o la scelta di una voce dei menù).
 */
int main(int argc, char *argv[]) {

	gtk_init(&argc, &argv);

/** 
 * Crea un nuovo oggetto GtkBuilder.
 */
    builder = gtk_builder_new();

/** 
 * Carica l'interfaccia grafica per l'utente.
 */    
	gtk_builder_add_from_file(builder,"forza4GUI.glade", NULL);

/** 
 * Connessione di tutti i segnali.
 */ 
    gtk_builder_connect_signals(builder, NULL);

/** 
 * Funzione di iniziallizzazione campo usata per cominciare nuove partite.
 */ 
	inizializza_campo();

/** 
 * Label del turno iniziale settata a ROSSO 
 * in quanto di default comincia il giocatore rosso.
 */ 
	GtkLabel *turn_label =GTK_LABEL(gtk_builder_get_object(builder,"label68"));
	gtk_label_set_text(turn_label, P1);
	
/** 
 * Partenza del ciclo di gestione degli eventi.
 */ 
    gtk_main();

	return 0;
}
